home *** CD-ROM | disk | FTP | other *** search
- /*
- * RequestString
- *
- * A program which requests a string from the user and prints it on
- * the standard output.
- *
- * Written by Peter Bengtsson who does not agree to be held responsible
- * for any damage or loss resulting from the use of this program.
- *
- * Use it as you wish for any and all nice things you can think of.
- */
-
- #include <proto/exec.h>
- #include <exec/memory.h>
- #include <clib/dos_protos.h>
- #include <pragmas/dos_pragmas.h>
- #include <clib/intuition_protos.h>
- #include <pragmas/intuition_pragmas.h>
- #include <clib/graphics_protos.h>
- #include <pragmas/graphics_pragmas.h>
- #include <clib/gadtools_protos.h>
- #include <pragmas/gadtools_pragmas.h>
- #include <graphics/gfxbase.h>
- #include <utility/tagitem.h>
- #include <utility/hooks.h>
- #include <intuition/sghooks.h>
- #include <intuition/intuition.h>
- #include <clib/alib_protos.h>
-
- #include <string.h>
-
- LONG __saveds RequestString(void);
- ULONG __saveds __asm HookFunc(register __a0 struct Hook *TheHook,
- register __a2 struct SGWork *Obj,
- register __a1 APTR Mess);
-
-
- #define TEMPLATE "STRING,TEXT/K,TITLE/K,NOGADS/S,WIDTH/N,SAFE/S,PERSIST/S,ENCRYPT/S,COMPARE/K,PUBSCREEN/K"
-
- #define NArgs 10 /* Number of arguments */
-
- #define STRING 0
- #define TEXT 1
- #define TITLE 2
- #define NOGADS 3
- #define WIDTH 4
- #define SAFE 5
- #define PERSIST 6
- #define ENCRYPT 7
- #define COMPARE 8
- #define PUBSCREEN 9
-
- #define MINWIDTH 8 /* Minimum width of gadget in characters */
-
- LONG __saveds RequestString(void)
- {
- struct DosLibrary *DOSBase=NULL;
- struct Library *GadToolsBase=NULL;
- struct IntuitionBase *IntuitionBase=NULL;
- struct GfxBase *GfxBase=NULL;
-
- LONG ArgList[NArgs];
- ULONG MsgClass=0;
- APTR VisInfo=NULL;
- char CBuffer[12],UName[48];
- struct TextExtent TExtent;
- struct Hook SGHook={0,0,0};
- struct RDArgs *Args=NULL;
- struct ExtIntuiMessage *EIMess=NULL;
- struct Gadget *Gad=NULL,*GList=NULL;
- struct Window *Win=NULL;
- struct Screen *Scr=NULL;
- char *ReturnText=NULL;
-
- int WWidth=0,WHeight=0;
- int GWidth=32,GHeight=1;
- long TXPos=0,TYPos=0;
-
- LONG Ret=20;
-
- const char *v="$VER: RequestString 39.4 (18.05.97)"; /* Bump this to 4X.1? */
-
- struct TagItem WindowTags[]={
- {WA_PubScreen,0},
- {WA_Gadgets,0},
- {WA_Left,0},
- {WA_Top,0},
- {WA_Width,0},
- {WA_Height,0},
- {WA_DragBar,FALSE},
- {WA_DepthGadget,FALSE},
- {WA_CloseGadget,FALSE},
- {WA_Title,NULL},
- {WA_IDCMP,IDCMP_GADGETUP|IDCMP_INACTIVEWINDOW|IDCMP_ACTIVEWINDOW|IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW},
- {WA_SizeGadget,FALSE},
- {WA_Activate,TRUE}
- };
-
- struct NewGadget StringGad={10,5,80,15,NULL,NULL,0,0L,NULL,NULL};
-
- if((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",39L))!=NULL){
- if((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39L))!=NULL){
- if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39L))!=NULL){
- if((GadToolsBase=OpenLibrary("gadtools.library",39L))!=NULL){
-
- memset(ArgList,0,NArgs*sizeof(LONG)); /* Clear the ArgList array */
-
- Args=ReadArgs(TEMPLATE,ArgList,NULL); /* How do we check for failure? */
- if((Scr=LockPubScreen((UBYTE *)ArgList[PUBSCREEN]))!=NULL){
- if((VisInfo=GetVisualInfo(Scr,NULL))!=NULL){
- if((Gad=CreateContext(&GList))!=NULL){
-
- if(ArgList[WIDTH]!=0)GWidth = *((LONG *)ArgList[WIDTH]);
- if(GWidth<8)GWidth=8;
-
- GHeight=GHeight*Scr->RastPort.TxHeight+6;
- WHeight=GHeight+8;
-
- do{
- GWidth=GWidth*Scr->RastPort.TxWidth+4;
- WWidth=GWidth+20;
- if(WWidth>Scr->Width)
- GWidth=(Scr->Width-20)/(Scr->RastPort.TxWidth)-1;
- }while(WWidth>Scr->Width);
-
- /* Forbid()/Permit() around this following poking in GfxBase? */
-
- FontExtent(GfxBase->DefaultFont,&TExtent);
-
- if(ArgList[TEXT]!=0){
- WHeight+=(TExtent.te_Height);
- if((TExtent.te_Width*strlen((char *)ArgList[TEXT])+20)>WWidth)
- WWidth=(TExtent.te_Width*strlen((char *)ArgList[TEXT])+20);
- }
-
- /* If the window has a title, it will also have a dragbar, closegadget
- * and a depthgadget.
- */
- if(ArgList[TITLE]!=0){
- WindowTags[6].ti_Data=TRUE;
- if(ArgList[NOGADS]==0){
- WindowTags[7].ti_Data=TRUE;
- WindowTags[8].ti_Data=TRUE;
- }
- WindowTags[9].ti_Data=(ULONG)ArgList[TITLE];
- WHeight+=Scr->RastPort.TxHeight; /* Should be Win->BorderTop, see also note below. */
- }
-
- StringGad.ng_VisualInfo=VisInfo;
- StringGad.ng_Width=GWidth;
- StringGad.ng_Height=GHeight;
- StringGad.ng_TopEdge=WHeight-(GHeight+4); /* The '4' should be replaces by Win->BorderTop but how? The window is not yet opened. */
- StringGad.ng_LeftEdge=(WWidth-GWidth)>>1;
-
- /* Initialize the Hook if we are using a safe stringgadget.
- * SGHook.d_Data points to storage space for the string which
- * will be returned. Memory sould be cleared.
- */
-
- if(ArgList[SAFE]!=0){
- SGHook.h_Entry=(unsigned long (*)())HookFunc;
- /* SGHook.h_SubEntry=NULL; */
- SGHook.h_Data=AllocVec(98,MEMF_ANY|MEMF_CLEAR); /* Should be made dynamic if possible */
- if(ArgList[STRING]!=0){
- int i = -1;
- strcpy((char *)SGHook.h_Data,(char *)ArgList[STRING]);
- while(((char *)ArgList[STRING])[++i]!=0)((char *)ArgList[STRING])[i]='*';
- }
- }
-
- /* Here goes nothing... */
-
- if((Gad=CreateGadget(STRING_KIND,Gad,&StringGad,GTST_EditHook,(ArgList[SAFE]==0)?NULL:&SGHook,GTST_String,ArgList[STRING],TAG_END))!=NULL){
-
- /* Screen Gadget */
- WindowTags[0].ti_Data=(ULONG)Scr;
- WindowTags[1].ti_Data=(ULONG)GList;
- /* Width & Height */
- WindowTags[4].ti_Data=(ULONG)WWidth;
- WindowTags[5].ti_Data=(ULONG)WHeight;
- /* X & Y Pos */
- WindowTags[2].ti_Data=(ULONG)(Scr->Width-WWidth)>>1;
- WindowTags[3].ti_Data=(ULONG)(Scr->Height-WHeight)>>1;
-
- if((Win=OpenWindowTagList(NULL,WindowTags))!=NULL){
-
- /* Is there some (un)informative text in the window? */
-
- if(ArgList[TEXT]!=0){
- SetAPen(Win->RPort,1); /* Colour should rather be selected with thougt to the background of the window, fix this. */
- TXPos=(WWidth-TextLength(Win->RPort,(char *)ArgList[TEXT],(unsigned long)strlen((char *)ArgList[TEXT])))>>1;
- TYPos=GfxBase->DefaultFont->tf_Baseline+Win->BorderTop+1;
- Move(Win->RPort,TXPos,TYPos);
- Text(Win->RPort,(char *)ArgList[TEXT],(unsigned long)strlen((char *)ArgList[TEXT]));
- }
-
- do{
-
- WaitPort(Win->UserPort);
-
- EIMess=(struct ExtIntuiMessage *)GT_GetIMsg(Win->UserPort);
-
- MsgClass=EIMess->eim_IntuiMessage.Class;
-
- GT_ReplyIMsg((struct IntuiMessage *)EIMess);
-
- switch(MsgClass) {
-
- case IDCMP_ACTIVEWINDOW :
- ActivateGadget(Gad,Win,NULL);
- break;
-
- case IDCMP_INACTIVEWINDOW :
- if(ArgList[PERSIST]){
- ScreenToFront(Win->WScreen);
- WindowToFront(Win);
- ActivateWindow(Win);
- }
- break;
-
- case IDCMP_REFRESHWINDOW :
- GT_BeginRefresh(Win);
- if(ArgList[TEXT]!=0){
- Move(Win->RPort,TXPos,TYPos);
- Text(Win->RPort,(char *)ArgList[TEXT],(unsigned long)strlen((char *)ArgList[TEXT]));
- }
- GT_EndRefresh(Win,TRUE);
- break;
-
-
- }
-
- }while((MsgClass!=IDCMP_GADGETUP) && (MsgClass!=IDCMP_CLOSEWINDOW));
-
- GT_GetGadgetAttrs(Gad,Win,NULL,GTST_String,&ReturnText,TAG_END);
-
- if(ArgList[SAFE]!=0)ReturnText=(char *)SGHook.h_Data;
-
- /* Try to find out who the user is if we are to encrypt the output. */
- /* I really don't know how to acquire the username, but this might */
- /* be a good guess of how to do it. */
-
- if(ArgList[ENCRYPT]!=0){
- if(GetVar("USER",UName,47,0L)==-1)
- if(GetVar("USERNAME",UName,47,0L)==-1)
- if(GetVar("LOGIN",UName,47,0L)==-1)
- UName[0]=0;
- ACrypt(CBuffer,ReturnText,UName);
- ReturnText=CBuffer;
- }
-
- Printf("\"%s\"\n",ReturnText);
-
- /* Here follows the COMPARE parameter. If the input string is not equal
- * to the argument of COMPARE we return WARN.
- */
-
- if(ArgList[COMPARE]!=0)
- Ret=(strcmp(ReturnText,(char *)ArgList[COMPARE]))?RETURN_WARN:0;
- else
- Ret=0;
-
- }}}} /* if:s */
-
- /* LockPubScreen failure only warrants a 10 if user defined a screen */
- } else if(ArgList[PUBSCREEN]!=0)Ret=10;
-
- /* Clean up. */
-
- if(SGHook.h_Data!=NULL)FreeVec(SGHook.h_Data);
- if(Args)FreeArgs(Args);
- if(Win)CloseWindow(Win);
- if(GList)FreeGadgets(GList);
- if(VisInfo)FreeVisualInfo(VisInfo);
- if(Scr)UnlockPubScreen(NULL,Scr);
-
- CloseLibrary(GadToolsBase);
- }
- CloseLibrary((struct Library *)IntuitionBase);
- }
- CloseLibrary((struct Library *)GfxBase);
- }
- CloseLibrary((struct Library *)DOSBase);
- }
-
- return(Ret);
-
- }
-
-
- /* EditHook function for safe stringgadgets */
-
-
- ULONG __saveds __asm HookFunc(register __a0 struct Hook *TheHook,
- register __a2 struct SGWork *Obj,
- register __a1 ULONG *Mess)
- {
- int i0,i1;
- char * const Tmp=(char *)(TheHook->h_Data);
-
- if(Mess[0]==SGH_KEY)
- {
- Obj->Actions|=SGA_USE;
-
- switch(Obj->EditOp)
- {
- case EO_DELBACKWARD :
- i0=Obj->StringInfo->BufferPos;
- i1=(Obj->StringInfo->NumChars)-(Obj->NumChars);
- strcpy(&Tmp[i0-i1],&Tmp[i0]);
- break;
-
- case EO_DELFORWARD :
- i0=Obj->StringInfo->BufferPos;
- i1=(Obj->StringInfo->NumChars)-(Obj->NumChars);
- strcpy(&Tmp[i0],&Tmp[i0+i1]);
- break;
-
- case EO_ENTER :
- /* Exit handling. */
- break;
-
- case EO_RESET :
- Tmp[0]=0;
- break;
-
- case EO_INSERTCHAR :
- if(strlen(Tmp)>96)Obj->Actions&=~SGA_USE;
- i0=Obj->StringInfo->BufferPos;
- Obj->WorkBuffer[i0]='*';
- i1=strlen(Tmp)+1;
- while(i1--!=i0)Tmp[i1+1]=Tmp[i1];
- Tmp[i0]=Obj->Code;
- break;
-
- case EO_CLEAR :
- Tmp[0]=0;
- break;
-
- case EO_BIGCHANGE : /* Not Allowed */
- case EO_UNDO :
- case EO_SPECIAL :
- Obj->Actions&=~SGA_USE;
- break;
- }
-
- return(~0);
- } else {
- Obj->Actions&=~SGA_USE;
-
- return(0);
- }
-
- }
-